ウェブアプリを作成する際に気をつかうのがユーザ・アカウントの管理である。自分でアカウント機構を作成する場合には、ID/パスワードが流出しないようにプログラミングする必要がある。また、万が一流出した際の対応などを考えると、できるだけアウトソーシングしたいという人も多いと思われる。
というわけで、今回はwebアプリのアカウント管理をアウトソーシングする方法として、Googleアカウント認証を利用する方法を確認する。Googleアカウント認証を利用するとユーザ認証(ID/パスワードによる認証等)をGoogleが行い、認証されたユーザ情報(名前、E-mailなど)をwebアプリで利用できるようになる。
■ ログインが必要なページを指定する
Google App Engine上でGoogleアカウントを利用する方法として、最も簡単なのがログインが必要なページを指定する方法である。具体的な方法としては、web.xml上でログインが必要なページのURLに対して「auth-constraint」タグで認証レベルを設定する。URL指定であるため、JSP・Servlet・htmlの区別なく設定可能である。以下に管理者権限を持つユーザのみ利用できるページ「admin.html」を指定するサンプルコードを示す。
◇関連リソース
TestGAE(プロジェクトフォルダ)
┣ src
┗ war
┣ WEB-INF
┃ ┗ web.xml
┗ admin.html
◇サンプルコード
<!-- 管理者用ページ -->
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin.html</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>administrator page</title>
</head>
<body>
管理者用ページです
</body>
</html>
◇実行結果
(ログインせずにアクセスした場合)
|
|
(管理権限でログインした場合)
|
(一般権限でログインした場合)
|
◇解説
上記は開発環境上(Eclipse上)で実行した例である。開発環境上では、ダミーのログイン画面が表示され、ログオンするユーザのE-Mailと管理者権限の有無を指定してログインのテストが行える。
「auth-constraint」タグで「admin」を指定すると(web.xml - 8行目)、管理者権限でGoogleにログインした場合は「admin.html」が表示され、ログインに成功しても管理者権限でない場合は403エラーが発生するようになる。ただ単にログインだけしてほしい場合には、「auth-constraint」タグで「*」を指定すればよい。なお、管理者権限の設定はGoogle Developers Consoleの「ツールとサービス - 権限」で行うことができる。
■ ログイン/ログアウト用のURLを作成する
検索エンジンなど、ログインしたユーザだけでなくログインしないユーザにもwebアプリが利用できるようにするには、Googleアカウントのログイン・ログアウト用のURLを利用する。Google App Engineにはログイン・ログアウト用のURLを作成するクラスが存在し、このURLでGoogle認証画面に遷移・認証が完了した後には、遷移するURLを指定できるようになっている。
以下に、Google App Engine上でGoogleアカウントのログイン・ログアウトURLを作成・利用するサンプルコードを示す。サンプルでは『http://localhost:8888/LoginGoogle』上に、Google認証用のリンクを作成し、ログイン時にはGoogleが持つユーザ情報を表示するようになっている。
◇サンプルコード
<servlet>
<servlet-name>LoginGoogle</servlet-name>
<servlet-class>com.appspot.karu_lab.LoginGoogleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginGoogle</servlet-name>
<url-pattern>/LoginGoogle</url-pattern>
</servlet-mapping>
package com.appspot.karu_lab;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
/**
* Googleアカウントのログイン・ログアウトを行う画面
* @author karura
*
*/
public class LoginGoogleServlet extends HttpServlet
{
/**
* GETパラメータによるURL起動
*/
public void doGet( HttpServletRequest req, HttpServletResponse resp ) throws IOException
{
// ページURLを取得
String url = req.getRequestURI();
// ユーザ情報を取得
UserService userService = UserServiceFactory.getUserService();
// 画面出力開始
PrintWriter out = resp.getWriter();
resp.setContentType("text/html");
out.println( "<html>" );
out.println( "<title>login / logout</title>");
out.println( "<a href=\"./\">home</a><br/><br/>" );
// ログイン状態か確認
if( userService.isUserLoggedIn() )
{
// ユーザ情報とログアウト用リンクの取得
String name = userService.getCurrentUser().getNickname();
String email = userService.getCurrentUser().getEmail();
String domain = userService.getCurrentUser().getAuthDomain();
String identity = userService.getCurrentUser().getFederatedIdentity();
String userID = userService.getCurrentUser().getUserId();
String logoutURL = userService.createLogoutURL( url );
// ユーザ情報を出力
out.println( String.format( "user : %s - <a href=\"%s\">logout</a><br/>" , name , logoutURL ) );
out.println( String.format( "userID : %s<br/>" , userID ) );
out.println( String.format( "email : %s<br/>" , email ) );
out.println( String.format( "domain : %s<br/>" , domain ) );
out.println( String.format( "identity : %s<br/>" , identity ) );
// 管理者の場合は更に出力
if( userService.isUserAdmin() ){ out.println( "you are the administrator.<br/>" ); }
}else{
// ログインURLを作成
String loginURL = userService.createLoginURL( url );
// ログインリンクを表示
out.println( String.format( "user : none - <a href='%s'>login</a>" , loginURL ) );
}
// フッター
out.println( "</html>" );
}
}
◇実行結果
(ログイン前)
|
(ログイン画面)
|
(管理者権限でログイン後)
|
(一般権限でログイン後)
|
◇解説
Google認証用のリンク・ユーザ情報はUserServiceクラスで作成・取得でき、インスタンスはUserServiceFactory.getUserService関数で取得できる(29行目)。サンプルではログイン状態かを確認し(39行目)、ログイン状態の場合はユーザ情報を表示(42行目~57行目)、そうでない場合はログインURLを作成(60行目~63行目)している。実行結果を見れば分かるが、開発環境上で実行した場合にはダミー用の認証画面が表示されるようになっている。
■ 参照
- Google App Engine Documentations:Users Java API Overview